package com.nanyang.tms.manager.export.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
import com.nanyang.common.core.dict.CommonEnum;
import com.nanyang.common.core.domain.ApiResult;
import com.nanyang.common.third.bos.entity.ObsRequestEntity;
import com.nanyang.common.third.bos.util.HwObsUtil;
import com.nanyang.common.tool.utils.convert.BeanUtils;
import com.nanyang.sys.api.dto.request.mq.ExportTaskMqRequest;
import com.nanyang.sys.api.service.task.ExportTaskRpcService;
import com.nanyang.tms.common.config.HwObsConfig;
import com.nanyang.tms.common.contstant.TmsCommonConsts;
import com.nanyang.tms.common.dict.TmsExceptionEnum;
import com.nanyang.tms.common.exception.TmsManagerException;
import com.nanyang.tms.common.util.TmsExceptionUtil;
import com.nanyang.tms.dao.forecast.ForecastDeclareDao;
import com.nanyang.tms.dao.forecast.ForecastReceiverDao;
import com.nanyang.tms.dao.shipment.ShipmentRelationDao;
import com.nanyang.tms.dao.waybill.WaybillDao;
import com.nanyang.tms.dao.waybill.WaybillShipmentVolumeDao;
import com.nanyang.tms.domain.export.ExportDataVO;
import com.nanyang.tms.domain.export.FillDataVO;
import com.nanyang.tms.domain.forecast.ForecastDeclareVO;
import com.nanyang.tms.domain.forecast.ForecastReceiverVO;
import com.nanyang.tms.domain.shipment.ShipmentRelationVO;
import com.nanyang.tms.domain.waybill.WaybillQuery;
import com.nanyang.tms.domain.waybill.WaybillShipmentVolumeVO;
import com.nanyang.tms.domain.waybill.WaybillVO;
import com.nanyang.tms.manager.export.ExportRelatedManager;
import io.seata.common.util.CollectionUtils;
import jodd.util.CollectionUtil;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.util.HtmlUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>CommonManagerImpl</p>
 * <p>Description:任务相关实现类</p>
 *
 * @author: bwl
 * date: 2020/12/8 10:01
 * @Copyright: 2020 www.rongetong.cn Inc. All rights reserved.
 */
@Slf4j
@Component
public class ExportRelatedManagerImpl implements ExportRelatedManager {


    @Reference(version = "1.0.0", timeout = 30000, check = false)
    private ExportTaskRpcService exportTaskRpcService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private HwObsConfig hwObsConfig;
    @Autowired
    private WaybillDao waybillDao;
    @Autowired
    private ShipmentRelationDao shipmentRelationDao;
    @Autowired
    private ForecastDeclareDao forecastDeclareDao;
    @Autowired
    private ForecastReceiverDao forecastReceiverDao;
    @Autowired
    private WaybillShipmentVolumeDao waybillShipmentVolumeDao;
    @Override
    public void exportDataMq(ExportDataVO exportDataVO) {
        try {
            if ("waybillData".equals(exportDataVO.getBusinessType())) {
                WaybillQuery waybillQuery = new WaybillQuery();
                if (StringUtil.isNotEmpty(exportDataVO.getFilterJson())) {
                    waybillQuery = JSONObject.parseObject(HtmlUtils.htmlUnescape(exportDataVO.getFilterJson()), WaybillQuery.class);
                }
                waybillQuery.setPageIndex(-1);
                waybillQuery.setWaybillType(1);
                List<WaybillVO> waybillVOS = waybillDao.listWaybill(waybillQuery);
                if (CollectionUtils.isEmpty(waybillVOS)){
                    throw new TmsManagerException(TmsExceptionEnum.WAYBILL_EXPORT_ERROR.getCode(),TmsExceptionEnum.WAYBILL_EXPORT_ERROR.getMessage());
                }
            }
            ExportTaskMqRequest exportTaskMqRequest = new ExportTaskMqRequest();
            BeanUtils.copyProperties(exportDataVO, exportTaskMqRequest);
            exportTaskMqRequest.setApplyName("admin");
            ApiResult<String> result = exportTaskRpcService.addExecuteTask(exportTaskMqRequest);
            if (result.getCode() != CommonEnum.REQUEST_SUCCESS.getCode()) {
                throw new TmsManagerException(result.getCode(), result.getMessage());
            }
            exportTaskMqRequest.setTaskCode(result.getData());
            rocketMQTemplate.asyncSend(TmsCommonConsts.EXPORT_TASK_TOPIC, exportTaskMqRequest, new SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    log.info(sendResult.toString());
                }
                @Override
                public void onException(Throwable e) {
                    throw new TmsManagerException(CommonEnum.SYSTEM_EXCEPTION.getCode(),CommonEnum.SYSTEM_EXCEPTION.getMessage(), e);
                }
            });
        } catch (Exception e) {
            throw TmsExceptionUtil.wrapException(e);
        }
    }

    @Override
    public String waybillExportData(WaybillQuery waybillQuery) {
        try {
            ObsRequestEntity entity = new ObsRequestEntity();
            /*******obs下载exel模板*********/
            BeanUtils.copyProperties(hwObsConfig, entity);
            String filePath=hwObsConfig.getWaybillExportPath();
            String templateUrl=hwObsConfig.getLocalFilePath()+ HwObsUtil.getObsFileName(filePath);
            HwObsUtil.getResourceFile(entity,filePath , templateUrl);
            /*******定义本地excel并生成数据*********/
            String fileName = hwObsConfig.getLocalFilePath()+ "Fill" + System.currentTimeMillis() + ".xlsx";
            EasyExcel.write(fileName).withTemplate(templateUrl).sheet("标准导入格式").doFill(data(waybillQuery));
            /*******obs上传excel文件*********/
            String uploadPath=hwObsConfig.getUploadFilePath()+"Fill"+System.currentTimeMillis()+".xlsx";
            String fileUrl = HwObsUtil.createFile(entity, uploadPath,new File(fileName) , true);
            /*******将本地文件删除*********/
            FileUtil.del(fileName);
            return fileUrl;
        } catch (Exception e) {
            log.error("导出excel：",e);
            throw TmsExceptionUtil.wrapException(e);
        }

    }

    private List<FillDataVO> data(WaybillQuery waybillQuery){
        List<FillDataVO> list=new ArrayList<>();
        waybillQuery.setPageIndex(-1);
        waybillQuery.setWaybillType(1);
        List<WaybillVO> waybillVOS = waybillDao.listWaybill(waybillQuery);
        Assert.notEmpty(waybillVOS,"waybillVOS is null");
        waybillVOS.forEach(waybillVO ->{
            ShipmentRelationVO shipmentRelationVO = shipmentRelationDao.selectByWaybillCode(waybillVO.getWaybillCode());
            Assert.notNull(shipmentRelationVO,"shipmentRelationVO is null");
            List<ForecastDeclareVO> forecastDeclareVOS = forecastDeclareDao.selectByCode(shipmentRelationVO.getForecastCode());
            Assert.notEmpty(forecastDeclareVOS,"forecastDeclareVOS is null");
            ForecastReceiverVO forecastReceiverVO = forecastReceiverDao.selectByCode(shipmentRelationVO.getForecastCode());
            Assert.notNull(forecastReceiverVO,"forecastReceiverVO is null");
            List<WaybillShipmentVolumeVO> waybillShipmentVolumeVOS = waybillShipmentVolumeDao.selectByCode(waybillVO.getWaybillCode());
            Assert.notEmpty(waybillShipmentVolumeVOS,"waybillShipmentVolumeVOS is null");
            List<FillDataVO> fillDataVOS = bulidFillData(waybillVO, forecastDeclareVOS, forecastReceiverVO, waybillShipmentVolumeVOS);
            list.addAll(fillDataVOS);
        });
        return list;
    }

    private List<FillDataVO> bulidFillData(WaybillVO waybillVO, List<ForecastDeclareVO> forecastDeclareVOS,ForecastReceiverVO forecastReceiverVO,List<WaybillShipmentVolumeVO> waybillShipmentVolumeVOS ){
        List<FillDataVO> list=new ArrayList<>();
        waybillShipmentVolumeVOS.forEach(waybillShipmentVolumeVO ->{
            FillDataVO fillDataVO=new FillDataVO();
            fillDataVO.setCustomerNo(waybillVO.getCustomerNo());
            fillDataVO.setSupplierNo(waybillVO.getSupplierNo());
            fillDataVO.setSupplierName(waybillVO.getSupplierName());
            fillDataVO.setCargoTypeName(waybillVO.getShipmentCargoTypeName());
            fillDataVO.setCountyCode(waybillVO.getCountyCode());
            fillDataVO.setTotalNum(waybillVO.getTotalNum());
            fillDataVO.setTotalWeight(waybillVO.getShipmentTotalWeight());
            fillDataVO.setRecipientName(forecastReceiverVO.getRecipientName());
            fillDataVO.setRecipientCompanyName(forecastReceiverVO.getRecipientCompanyName());
            fillDataVO.setTel(forecastReceiverVO.getTel());
            fillDataVO.setMobile(forecastReceiverVO.getMobile());
            fillDataVO.setProvince(forecastReceiverVO.getProvince());
            fillDataVO.setCity(forecastReceiverVO.getCity());
            fillDataVO.setZipCode(forecastReceiverVO.getZipCode());
            fillDataVO.setAddress(forecastReceiverVO.getAddress());
            for (int i = 0; i < forecastDeclareVOS.size(); i++) {
                if(i==0){
                    fillDataVO.setFstNameCn(forecastDeclareVOS.get(0).getNameCn());
                    fillDataVO.setFstNameEn(forecastDeclareVOS.get(0).getNameEn());
                    fillDataVO.setFstQuantity(forecastDeclareVOS.get(0).getQuantity());
                    fillDataVO.setFstWeight(forecastDeclareVOS.get(0).getWeight());
                    fillDataVO.setFstTotalPrice(forecastDeclareVOS.get(0).getTotalPrice());
                    fillDataVO.setFstPrice(forecastDeclareVOS.get(0).getPrice());
                    fillDataVO.setFstCurrency("USD");
                    fillDataVO.setFstCustomsNo(forecastDeclareVOS.get(0).getCustomsNo());
                }else if(i==1){
                    fillDataVO.setSndNameCn(forecastDeclareVOS.get(1).getNameCn());
                    fillDataVO.setSndNameEn(forecastDeclareVOS.get(1).getNameEn());
                    fillDataVO.setSndQuantity(forecastDeclareVOS.get(1).getQuantity());
                    fillDataVO.setSndWeight(forecastDeclareVOS.get(1).getWeight());
                    fillDataVO.setSndTotalPrice(forecastDeclareVOS.get(1).getTotalPrice());
                    fillDataVO.setSndPrice(forecastDeclareVOS.get(1).getPrice());
                    fillDataVO.setSndCurrency("USD");
                    fillDataVO.setSndCustomsNo(forecastDeclareVOS.get(1).getCustomsNo());
                }else if(i==2){
                    fillDataVO.setTrdNameCn(forecastDeclareVOS.get(2).getNameCn());
                    fillDataVO.setTrdNameEn(forecastDeclareVOS.get(2).getNameEn());
                    fillDataVO.setTrdQuantity(forecastDeclareVOS.get(2).getQuantity());
                    fillDataVO.setTrdWeight(forecastDeclareVOS.get(2).getWeight());
                    fillDataVO.setTrdTotalPrice(forecastDeclareVOS.get(2).getTotalPrice());
                    fillDataVO.setTrdPrice(forecastDeclareVOS.get(2).getPrice());
                    fillDataVO.setTrdCurrency("USD");
                    fillDataVO.setTrdCustomsNo(forecastDeclareVOS.get(2).getCustomsNo());
                }
            }
            fillDataVO.setWeight(waybillShipmentVolumeVO.getWeight());
            fillDataVO.setLength(waybillShipmentVolumeVO.getLength());
            fillDataVO.setWidth(waybillShipmentVolumeVO.getWidth());
            fillDataVO.setHeight(waybillShipmentVolumeVO.getHeight());
            fillDataVO.setPiece(1);
            list.add(fillDataVO);
        });
        return list;
    }

}
